home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / CGIHTTPServer.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  11KB  |  379 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. """CGI-savvy HTTP Server.
  5.  
  6. This module builds on SimpleHTTPServer by implementing GET and POST
  7. requests to cgi-bin scripts.
  8.  
  9. If the os.fork() function is not present (e.g. on Windows),
  10. os.popen2() is used as a fallback, with slightly altered semantics; if
  11. that function is not present either (e.g. on Macintosh), only Python
  12. scripts are supported, and they are executed by the current process.
  13.  
  14. In all cases, the implementation is intentionally naive -- all
  15. requests are executed sychronously.
  16.  
  17. SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL
  18. -- it may execute arbitrary Python code or external programs.
  19.  
  20. Note that status code 200 is sent prior to execution of a CGI script, so
  21. scripts cannot send other status codes such as 302 (redirect).
  22. """
  23. __version__ = '0.4'
  24. __all__ = [
  25.     'CGIHTTPRequestHandler']
  26. import os
  27. import sys
  28. import urllib
  29. import BaseHTTPServer
  30. import SimpleHTTPServer
  31. import select
  32.  
  33. class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  34.     '''Complete HTTP server with GET, HEAD and POST commands.
  35.  
  36.     GET and HEAD also support running CGI scripts.
  37.  
  38.     The POST command is *only* implemented for CGI scripts.
  39.  
  40.     '''
  41.     have_fork = hasattr(os, 'fork')
  42.     have_popen2 = hasattr(os, 'popen2')
  43.     have_popen3 = hasattr(os, 'popen3')
  44.     rbufsize = 0
  45.     
  46.     def do_POST(self):
  47.         '''Serve a POST request.
  48.  
  49.         This is only implemented for CGI scripts.
  50.  
  51.         '''
  52.         if self.is_cgi():
  53.             self.run_cgi()
  54.         else:
  55.             self.send_error(501, 'Can only POST to CGI scripts')
  56.  
  57.     
  58.     def send_head(self):
  59.         '''Version of send_head that support CGI scripts'''
  60.         if self.is_cgi():
  61.             return self.run_cgi()
  62.         return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
  63.  
  64.     
  65.     def is_cgi(self):
  66.         """Test whether self.path corresponds to a CGI script,
  67.         and return a boolean.
  68.  
  69.         This function sets self.cgi_info to a tuple (dir, rest)
  70.         when it returns True, where dir is the directory part before
  71.         the CGI script name.  Note that rest begins with a
  72.         slash if it is not empty.
  73.  
  74.         The default implementation tests whether the path
  75.         begins with one of the strings in the list
  76.         self.cgi_directories (and the next character is a '/'
  77.         or the end of the string).
  78.         """
  79.         path = self.path
  80.         for x in self.cgi_directories:
  81.             i = len(x)
  82.             if path[:i] == x:
  83.                 if not path[i:] or path[i] == '/':
  84.                     self.cgi_info = (path[:i], path[i + 1:])
  85.                     return True
  86.         return False
  87.  
  88.     cgi_directories = [
  89.         '/cgi-bin',
  90.         '/htbin']
  91.     
  92.     def is_executable(self, path):
  93.         '''Test whether argument path is an executable file.'''
  94.         return executable(path)
  95.  
  96.     
  97.     def is_python(self, path):
  98.         '''Test whether argument path is a Python script.'''
  99.         (head, tail) = os.path.splitext(path)
  100.         return tail.lower() in ('.py', '.pyw')
  101.  
  102.     
  103.     def run_cgi(self):
  104.         '''Execute a CGI script.'''
  105.         path = self.path
  106.         (dir, rest) = self.cgi_info
  107.         i = path.find('/', len(dir) + 1)
  108.         while i >= 0:
  109.             nextdir = path[:i]
  110.             nextrest = path[i + 1:]
  111.             scriptdir = self.translate_path(nextdir)
  112.             if os.path.isdir(scriptdir):
  113.                 dir = nextdir
  114.                 rest = nextrest
  115.                 i = path.find('/', len(dir) + 1)
  116.                 continue
  117.             break
  118.         i = rest.rfind('?')
  119.         if i >= 0:
  120.             rest = rest[:i]
  121.             query = rest[i + 1:]
  122.         else:
  123.             query = ''
  124.         i = rest.find('/')
  125.         if i >= 0:
  126.             script = rest[:i]
  127.             rest = rest[i:]
  128.         else:
  129.             script = rest
  130.             rest = ''
  131.         scriptname = dir + '/' + script
  132.         scriptfile = self.translate_path(scriptname)
  133.         if not os.path.exists(scriptfile):
  134.             self.send_error(404, 'No such CGI script (%r)' % scriptname)
  135.             return None
  136.         if not os.path.isfile(scriptfile):
  137.             self.send_error(403, 'CGI script is not a plain file (%r)' % scriptname)
  138.             return None
  139.         ispy = self.is_python(scriptname)
  140.         env = { }
  141.         env['SERVER_SOFTWARE'] = self.version_string()
  142.         env['SERVER_NAME'] = self.server.server_name
  143.         env['GATEWAY_INTERFACE'] = 'CGI/1.1'
  144.         env['SERVER_PROTOCOL'] = self.protocol_version
  145.         env['SERVER_PORT'] = str(self.server.server_port)
  146.         env['REQUEST_METHOD'] = self.command
  147.         uqrest = urllib.unquote(rest)
  148.         env['PATH_INFO'] = uqrest
  149.         env['PATH_TRANSLATED'] = self.translate_path(uqrest)
  150.         env['SCRIPT_NAME'] = scriptname
  151.         host = self.address_string()
  152.         if host != self.client_address[0]:
  153.             env['REMOTE_HOST'] = host
  154.         
  155.         env['REMOTE_ADDR'] = self.client_address[0]
  156.         authorization = self.headers.getheader('authorization')
  157.         if authorization:
  158.             authorization = authorization.split()
  159.             if len(authorization) == 2:
  160.                 import base64 as base64
  161.                 import binascii as binascii
  162.                 env['AUTH_TYPE'] = authorization[0]
  163.                 if authorization[0].lower() == 'basic':
  164.                     
  165.                     try:
  166.                         authorization = base64.decodestring(authorization[1])
  167.                     except binascii.Error:
  168.                         pass
  169.  
  170.                     authorization = authorization.split(':')
  171.                     if len(authorization) == 2:
  172.                         env['REMOTE_USER'] = authorization[0]
  173.                     
  174.                 
  175.             
  176.         
  177.         if self.headers.typeheader is None:
  178.             env['CONTENT_TYPE'] = self.headers.type
  179.         else:
  180.             env['CONTENT_TYPE'] = self.headers.typeheader
  181.         length = self.headers.getheader('content-length')
  182.         if length:
  183.             env['CONTENT_LENGTH'] = length
  184.         
  185.         referer = self.headers.getheader('referer')
  186.         if referer:
  187.             env['HTTP_REFERER'] = referer
  188.         
  189.         accept = []
  190.         for line in self.headers.getallmatchingheaders('accept'):
  191.             if line[:1] in '\t\n\r ':
  192.                 accept.append(line.strip())
  193.                 continue
  194.             accept = accept + line[7:].split(',')
  195.         
  196.         env['HTTP_ACCEPT'] = ','.join(accept)
  197.         ua = self.headers.getheader('user-agent')
  198.         if ua:
  199.             env['HTTP_USER_AGENT'] = ua
  200.         
  201.         co = filter(None, self.headers.getheaders('cookie'))
  202.         if co:
  203.             env['HTTP_COOKIE'] = ', '.join(co)
  204.         
  205.         for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH', 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
  206.             env.setdefault(k, '')
  207.         
  208.         os.environ.update(env)
  209.         self.send_response(200, 'Script output follows')
  210.         decoded_query = query.replace('+', ' ')
  211.         if self.have_fork:
  212.             args = [
  213.                 script]
  214.             if '=' not in decoded_query:
  215.                 args.append(decoded_query)
  216.             
  217.             nobody = nobody_uid()
  218.             self.wfile.flush()
  219.             pid = os.fork()
  220.             if pid != 0:
  221.                 (pid, sts) = os.waitpid(pid, 0)
  222.                 while select.select([
  223.                     self.rfile], [], [], 0)[0]:
  224.                     if not self.rfile.read(1):
  225.                         break
  226.                         continue
  227.                 if sts:
  228.                     self.log_error('CGI script exit status %#x', sts)
  229.                 
  230.                 return None
  231.             
  232.             try:
  233.                 
  234.                 try:
  235.                     os.setuid(nobody)
  236.                 except os.error:
  237.                     pid != 0
  238.                     pid != 0
  239.                 except:
  240.                     pid != 0
  241.  
  242.                 os.dup2(self.rfile.fileno(), 0)
  243.                 os.dup2(self.wfile.fileno(), 1)
  244.                 os.execve(scriptfile, args, os.environ)
  245.             self.server.handle_error(self.request, self.client_address)
  246.             os._exit(127)
  247.  
  248.         elif self.have_popen2 or self.have_popen3:
  249.             import shutil as shutil
  250.             if self.have_popen3:
  251.                 popenx = os.popen3
  252.             else:
  253.                 popenx = os.popen2
  254.             cmdline = scriptfile
  255.             if self.is_python(scriptfile):
  256.                 interp = sys.executable
  257.                 if interp.lower().endswith('w.exe'):
  258.                     interp = interp[:-5] + interp[-4:]
  259.                 
  260.                 cmdline = '%s -u %s' % (interp, cmdline)
  261.             
  262.             if '=' not in query and '"' not in query:
  263.                 cmdline = '%s "%s"' % (cmdline, query)
  264.             
  265.             self.log_message('command: %s', cmdline)
  266.             
  267.             try:
  268.                 nbytes = int(length)
  269.             except (TypeError, ValueError):
  270.                 nbytes = 0
  271.  
  272.             files = popenx(cmdline, 'b')
  273.             fi = files[0]
  274.             fo = files[1]
  275.             if self.have_popen3:
  276.                 fe = files[2]
  277.             
  278.             if self.command.lower() == 'post' and nbytes > 0:
  279.                 data = self.rfile.read(nbytes)
  280.                 fi.write(data)
  281.             
  282.             while select.select([
  283.                 self.rfile._sock], [], [], 0)[0]:
  284.                 if not self.rfile._sock.recv(1):
  285.                     break
  286.                     continue
  287.             fi.close()
  288.             shutil.copyfileobj(fo, self.wfile)
  289.             if self.have_popen3:
  290.                 errors = fe.read()
  291.                 fe.close()
  292.                 if errors:
  293.                     self.log_error('%s', errors)
  294.                 
  295.             
  296.             sts = fo.close()
  297.             if sts:
  298.                 self.log_error('CGI script exit status %#x', sts)
  299.             else:
  300.                 self.log_message('CGI script exited OK')
  301.         else:
  302.             save_argv = sys.argv
  303.             save_stdin = sys.stdin
  304.             save_stdout = sys.stdout
  305.             save_stderr = sys.stderr
  306.             
  307.             try:
  308.                 save_cwd = os.getcwd()
  309.                 
  310.                 try:
  311.                     sys.argv = [
  312.                         scriptfile]
  313.                     if '=' not in decoded_query:
  314.                         sys.argv.append(decoded_query)
  315.                     
  316.                     sys.stdout = self.wfile
  317.                     sys.stdin = self.rfile
  318.                     execfile(scriptfile, {
  319.                         '__name__': '__main__' })
  320.                 finally:
  321.                     sys.argv = save_argv
  322.                     sys.stdin = save_stdin
  323.                     sys.stdout = save_stdout
  324.                     sys.stderr = save_stderr
  325.                     os.chdir(save_cwd)
  326.  
  327.             except SystemExit:
  328.                 sts = None
  329.                 self.log_error('CGI script exit status %s', str(sts))
  330.  
  331.             self.log_message('CGI script exited OK')
  332.  
  333.  
  334. nobody = None
  335.  
  336. def nobody_uid():
  337.     """Internal routine to get nobody's uid"""
  338.     global nobody
  339.     if nobody:
  340.         return nobody
  341.     
  342.     try:
  343.         import pwd as pwd
  344.     except ImportError:
  345.         nobody
  346.         nobody
  347.         return -1
  348.  
  349.     
  350.     try:
  351.         nobody = pwd.getpwnam('nobody')[2]
  352.     except KeyError:
  353.         nobody
  354.         nobody
  355.         nobody = 1 + max(map((lambda x: x[2]), pwd.getpwall()))
  356.     except:
  357.         nobody
  358.  
  359.     return nobody
  360.  
  361.  
  362. def executable(path):
  363.     '''Test for executable file.'''
  364.     
  365.     try:
  366.         st = os.stat(path)
  367.     except os.error:
  368.         return False
  369.  
  370.     return st.st_mode & 73 != 0
  371.  
  372.  
  373. def test(HandlerClass = CGIHTTPRequestHandler, ServerClass = BaseHTTPServer.HTTPServer):
  374.     SimpleHTTPServer.test(HandlerClass, ServerClass)
  375.  
  376. if __name__ == '__main__':
  377.     test()
  378.  
  379.